﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Linq;
using System.Linq;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web;
using MLY.Dal;
using MLY.Bll;
using System.Drawing;
using System.Threading;
using System.Globalization;
using DevExpress.Web.Data;
using DevExpress.Data.Linq;
using DevExpress.Web.ASPxGridView;
using DevExpress.Web.ASPxEditors;
using DevExpress.Web.ASPxGridView.Export;
using DevExpress.Utils;
using System.Web.UI.HtmlControls;

namespace MLY.LTR
{
    public partial class Inventory : Bll.BasePage
    {
        private string InitTitle;
        private int DaysAgoAllowed = 7;
        private int CurrentrowNum = 1;
        #region Events

        private string CurDate()
        {
            return DateTime.Now.Minute.ToString() + ":" + DateTime.Now.Second.ToString() + "," + DateTime.Now.Millisecond.ToString();
        }

        //protected void Page_PreRender(object sender, EventArgs e)
        //{
        //    Log.WriteInfo("PreRender: " + CurDate());
        //}
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
                InitTitle = Dictionary.Translate("Master.Title");
            else
                Title = InitTitle;

            if (!IsPostBack && Request.QueryString["doPostBack"] == null)
            {
                if (Request.ServerVariables["HTTP_REFERER"] != null)
                    ViewState["Referer"] = Request.ServerVariables["HTTP_REFERER"];
                else
                    ViewState["Referer"] = this.Request.Url.ToString();

                ShowSpliter(false);
                SetErrorMessage("");
            }

            if (!IsPostBack)
            {
                SessParam.ContractorID = SessParam.CustomerId = "";
                SetClient();

                if (SessParam.IsClient)
                {
                    InventoryGrid.Columns["ContractorOrganizationName"].Visible = true;
                    InventoryGrid.Columns["CustomerOrganizationName"].Visible = false;
                }
                else
                {
                    InventoryGrid.Columns["ContractorOrganizationName"].Visible = false;
                    InventoryGrid.Columns["CustomerOrganizationName"].Visible = true;
                }


                if (SessParam.Culture == "he")
                {
                    InventoryGrid.RightToLeft = DefaultBoolean.True;
                    InventoryGrid.Styles.Header.HorizontalAlign = HorizontalAlign.Right;
                }
                else
                {
                    InventoryGrid.RightToLeft = DefaultBoolean.False;
                    InventoryGrid.Styles.Header.HorizontalAlign = HorizontalAlign.Left;
                }


                int UserId = int.Parse(Session["UserId"].ToString());
                Bll.clsUser user = new MLY.Bll.clsUser(UserId);

                if (user.Data.DefaultLinesinGrid.HasValue)
                    InventoryGrid.SettingsPager.PageSize = user.Data.DefaultLinesinGrid.Value;
                else
                    InventoryGrid.SettingsPager.PageSize = 10;

                DeleteSelectedButton.Visible = ((SessParam.RoleId == 60) || (SessParam.OrganizationId == 51) ||     
                                                                            (SessParam.OrganizationId == 52) ||
                                                                            (SessParam.OrganizationId == 53)); 
                MarkSelectedDebate.Visible = (SessParam.OrganizationId == 25 || SessParam.OrganizationId == 46);


                DeleteReasonsDataSource.SelectParameters.Add("OrganizationId", SessParam.OrganizationId.ToString());

                // for lithotech - changing columns order:
                if (SessParam.OrganizationId == 51)
                {
                    InventoryGrid.Columns[19].VisibleIndex = 11;
                    InventoryGrid.Columns[8].VisibleIndex = 12;
                    InventoryGrid.Columns[27].VisibleIndex = 13;
                    InventoryGrid.Columns[9].VisibleIndex = 14;
                    InventoryGrid.Columns[12].VisibleIndex = 15;
                    InventoryGrid.Columns[20].VisibleIndex = 16;
                    InventoryGrid.Columns[5].VisibleIndex = 17;
                    InventoryGrid.Columns[21].VisibleIndex = 18;
                    InventoryGrid.Columns[17].VisibleIndex = 19;
                    InventoryGrid.Columns[18].VisibleIndex = 20;                   
                    
                }
                
                
                /// DEMO CODE
                //if (UserId == 39)
                //{
                //    if ((string)Session["DemoStage"] == "Inventory")
                //    {
                //        ExportToXLS.CssClass = "demohighlight";
                //        Demo.MoveToNextDemoSubStage();
                //        DemoEnabled.Value = "yes";
                //    }
                //    else
                //        ExportToXLS.CssClass = "demostophighlight";

                //    if ((string)Session["DemoStage"] == "Alerts")
                //    {
                //        Demo.MoveToNextDemoSubStage();
                //    } 
                //}
                /// END OF DEMO CODE
                /// 

                
            }

            InitializeDataSource();
            InventoryGrid.Templates.EditForm = new InventoryEditForm(); 

            // Special case for Lithotec to improve performance of page load:
            if (SessParam.OrganizationId == 51 ||
                SessParam.OrganizationId == 52 ||
                SessParam.OrganizationId == 53)
            {
                InventoryDataSource.StoreOriginalValuesInViewState = false;
                InventoryGrid.Columns[2].Visible = false;
            }
            else
            {
                InventoryGrid.Columns[1].Visible = false;
                Inv1Link.Visible = false;
            }

            //InventorySQLDataSource.SelectCommand = SQLDataSourceCommandText();
            //InventoryGrid.Templates.EditForm = new InventoryEditForm();

        }

        protected bool IsLithoteck()
        {
            return (SessParam.OrganizationId == 51 || 
                    SessParam.OrganizationId == 52 ||
                    SessParam.OrganizationId == 53);
        }

//        public string SQLDataSourceCommandText()
//        {
//            return @"SELECT * FROM WorkOrdersView 
//                     WHERE (originalWoForDist IS NULL) 
//                       AND " + (SessParam.IsClient ? "CustomerId = " + SessParam.OrganizationId.ToString() : "ContractorId = " + SessParam.OrganizationId) +
//                     @"AND (ActualDelivaryDate IS NULL OR ActualDelivaryDate <> '2099-01-01')
//                       ORDER BY 
//                        CASE WHEN ActualDelivaryDate IS NULL THEN CONVERT(bit, 1) ELSE Convert(bit, 0) END DESC,
//                        ActualDelivaryDate desc,
//                        CASE WHEN DateFieldB IS NULL THEN CONVERT(bit, 1) ELSE Convert(bit, 0) END DESC,
//                        DateFieldB desc,
//                        CASE WHEN PlannedDelivaryDate IS NULL THEN CONVERT(bit, 1) ELSE Convert(bit, 0) END DESC,
//                        PlannedDelivaryDate desc, WorkOrderId DESC";

//        }

        
        protected void InventoryGrid_StartRowEditing(object sender, ASPxStartRowEditingEventArgs e)
        {
            SessParam.WorkOrderEditing = true;
        }

        protected void InventoryGrid_CancelRowEditing(object sender, ASPxStartRowEditingEventArgs e)
        {
            SessParam.WorkOrderEditing = false;
            SetEditFormErrorMessage("");
        }

        protected void InventoryGrid_RowUpdated(object sender, ASPxDataUpdatedEventArgs e)
        {
            SessParam.WorkOrderEditing = false;
            
            // Alerts - sending emails.
            //Utils.CheckAlerts();
            //Utils.SendPendingAlerts();
        }

        protected void InventoryGrid_RowInserted(object sender, ASPxDataInsertedEventArgs e)
        {
            SetEditFormErrorMessage("");
            
            // Alerts - sending emails.
            //Utils.CheckAlerts();
           // Utils.SendPendingAlerts();
            
        }

        protected void InventoryGrid_RowInserting(object sender, ASPxDataInsertingEventArgs e)
        {
            if (InventoryGrid.Templates == null || !(InventoryGrid.Templates.EditForm is InventoryEditForm))
                return;
            
            

            InventoryEditForm editForm = (InventoryEditForm)InventoryGrid.Templates.EditForm;
            EditFormDictionary editFormDictionary = editForm.mEditFormDictionary;
            foreach (KeyValuePair<string, EditFormControl> kvp in editFormDictionary)
            {
                EditFormControl editFormControl = (EditFormControl)kvp.Value;
                string fieldName = editFormControl.mFieldName;

                if (editFormControl.mControl is ASPxTextBox)
                {
                    if (string.IsNullOrEmpty(fieldName))
                        continue;

                    ASPxTextBox textBox = (ASPxTextBox)editFormControl.mControl;
                    string text = textBox.Text;

                    if (string.IsNullOrEmpty(text))
                    {
                        // Supplier Work Order Number 
                        if (!SessParam.IsClient)
                        {
                            if (TestField(kvp, InventoryEditForm.mContractorWorkOrderNumberTextBox,
                                          Dictionary.SupplierWorkOrderNumber, e))
                                return;
                        }
                        if (SessParam.IsClient)
                        {
                            // Client Work Order Number
                            if (TestField(kvp, InventoryEditForm.mClientWorkOrderNumberTextBox,
                                          Dictionary.ClientWorkOrderNumber, e))
                                return;
                        }

                        // Quantity 
                        if (TestField(kvp, InventoryEditForm.mQuantityTextBox, Dictionary.Quantity, e))
                            return;
                    }
                    e.SetNewValueStr(fieldName, text);
                }
                else
                    if (editFormControl.mControl is ASPxDateEdit)
                    {
                        if (string.IsNullOrEmpty(fieldName))
                            continue;
                        ASPxDateEdit dateBox = (ASPxDateEdit)editFormControl.mControl;

                        //if (dateBox.Date < Utils.DateXWorkDaysAgo(DaysAgoAllowed) && dateBox.Date > Utils.MinSqlDateTime)
                        //{
                        //    SetEditFormErrorMessage(fieldName + " is earlier than " + DaysAgoAllowed.ToString() + " days ago");
                        //    e.Cancel = true;
                        //    return;
                        //}
                        //else
                            e.SetNewValueDateTime(fieldName, dateBox.Date);
                    }
                    else
                        if (editFormControl.mControl is ASPxSpinEdit)
                        {
                            if (string.IsNullOrEmpty(fieldName))
                                continue;
                            ASPxSpinEdit spinEdit = (ASPxSpinEdit)editFormControl.mControl;
                            decimal number = spinEdit.Number;
                            if (spinEdit.MinValue <= number && number <= spinEdit.MaxValue)
                                e.SetNewValueInt(fieldName, (int)number);
                            else
                                e.SetNewValueIntNull(fieldName);
                        }
                        else
                            if (editFormControl.mControl is ASPxComboBox)
                            {
                                if (string.IsNullOrEmpty(fieldName))
                                {
                                    if (kvp.Key == InventoryEditForm.mContractorIdComboBox)
                                    {
                                        ASPxComboBox comboBox = (ASPxComboBox)editFormControl.mControl;
                                        if (string.IsNullOrEmpty(comboBox.Text))
                                        {
                                            // Supplier Id 
                                            SetMissingErrorMessage(Dictionary.SupplierId);
                                            e.Cancel = true;
                                            return;
                                        }
                                        e.SetNewValueInt(TableWorkOrder.cnContractorId, int.Parse(comboBox.Value.ToString()));
                                    }
                                    else if (kvp.Key == "TextFieldBTextBox")
                                    {
                                        ASPxComboBox comboBox = (ASPxComboBox)editFormControl.mControl;
                                        if (comboBox.Value == null)
                                            e.SetNewValueStr(TableWorkOrder.cnTextFieldB, "");
                                        e.SetNewValueStr(TableWorkOrder.cnTextFieldB, comboBox.Value.ToString());
                                    }
                                    continue;
                                }
                                else if (fieldName == "TextFieldB")
                                {
                                    ASPxComboBox comboBox = (ASPxComboBox)editFormControl.mControl;
                                    if (comboBox.Value == null)
                                        e.SetNewValueStr(TableWorkOrder.cnTextFieldB, "");
                                    e.SetNewValueStr(TableWorkOrder.cnTextFieldB, comboBox.Value.ToString());
                                }
                            }
            }

            // inserting user organization id for the work order
            if (SessParam.IsClient)
            {
                e.SetNewValueStr("CustomerId", SessParam.OrganizationId.ToString());
            }
            else
            {
                // a bug workaround: for some reason, in the edit form, customer Id is not instantiated, and 
                // goes into the contractorId column. Need to fix this in the edit form itself.
                e.SetNewValueStr("CustomerId", e.NewValues["ContractorId"].ToString());
                e.SetNewValueStr("ContractorId", SessParam.OrganizationId.ToString());
            }

            // update by and updated date values
            e.SetNewValueInt("UpdateBy", SessParam.UserId);
            e.SetNewValueDateTime("UpdateDate", DateTime.Now);
            e.SetNewValueDateTime("DateCreated", DateTime.Now);
        }

        protected void InventoryGrid_RowUpdating(object sender, ASPxDataUpdatingEventArgs e)
        {
            if (InventoryGrid.Templates == null || !(InventoryGrid.Templates.EditForm is InventoryEditForm))
                return;
            bool isDistribution = false;
            InventoryEditForm editForm = (InventoryEditForm)InventoryGrid.Templates.EditForm;
            EditFormDictionary editFormDictionary = editForm.mEditFormDictionary;
            foreach (KeyValuePair<string, EditFormControl> kvp in editFormDictionary)
            {
                EditFormControl editFormControl = (EditFormControl)kvp.Value;
                string fieldName = editFormControl.mFieldName;

                if (!editFormControl.mControl.Enabled)
                    continue;

                if (editFormControl.mControl is ASPxTextBox)
                {
                    ASPxTextBox textBox = (ASPxTextBox)editFormControl.mControl;

                    bool isQuantity = kvp.Key == InventoryEditForm.mSentQuantityTextBox;
                    if (isQuantity)
                    {
                        // Update Quantity and if necessary make distribution.
                        UpdateQuantity(textBox, ref isDistribution, editForm, e);
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(fieldName))
                            continue;
                        e.SetNewValueStr(fieldName, textBox.Text);
                    }
                }
                else
                    if (editFormControl.mControl is ASPxDateEdit)
                    {
                        if (string.IsNullOrEmpty(fieldName))
                            continue;
                        ASPxDateEdit dateBox = (ASPxDateEdit)editFormControl.mControl;
                        if (fieldName == TableWorkOrder.cnActualDelivaryDate)
                            e.SetNewValueDateTime(fieldName, dateBox.Date, null);
                        else
                            e.SetNewValueDateTime(fieldName, dateBox.Date);
                    }
                    else
                        if (editFormControl.mControl is ASPxSpinEdit)
                        {
                            if (string.IsNullOrEmpty(fieldName))
                                continue;
                            ASPxSpinEdit spinEdit = (ASPxSpinEdit)editFormControl.mControl;
                            try
                            {
                                e.SetNewValueInt(fieldName, (int)spinEdit.Number);
                            }
                            catch
                            {
                                e.SetNewValueIntNull(fieldName);
                            }
                        }
                    else
                        if (editFormControl.mControl is ASPxComboBox)
                        {
                            if (string.IsNullOrEmpty(fieldName))
                                continue;
                            
                            ASPxComboBox comboBox = (ASPxComboBox)editFormControl.mControl;
                            if (comboBox.Value == null)
                                e.SetNewValueStr(fieldName, "");
                            e.SetNewValueStr(fieldName, comboBox.Value.ToString());
                        }
            }

            if (isDistribution)
            {
                // In create distribution, set actual delivary date to null.
                e.SetNewValueDateTime(TableWorkOrder.cnActualDelivaryDate, null);
            }

            // update by and updated date values
            e.SetNewValueInt("UpdateBy", SessParam.UserId);
            e.SetNewValueDateTime("UpdateDate", DateTime.Now);
            
            if (!CheckDates(e.Keys["WorkOrderId"].ToString(),
                e.NewValues["SendDate"], e.NewValues["RequestedDelivaryDate"],
                e.NewValues["PlannedDelivaryDate"], e.NewValues["ActualDelivaryDate"],
                e.NewValues["DateFieldA"], e.NewValues["DateFieldB"],
                e.NewValues["OriginalPlannedDeliveryDate"], e.NewValues["OriginalRequestedDeliveryDate"]))
                e.Cancel = true;

            //Utils.CheckAlerts();
            //Utils.SendPendingAlerts();
               
        }

        

        private bool CheckDates(string WorkOrderId, object SendDate, object RequestedDelivaryDate,
                                object PlannedDelivaryDate, object ActualDelivaryDate, object DateFieldA, object DateFieldB,
                                object OriginalPlannedDeliveryDate, object OriginalRequestedDeliveryDate)
        {
            bool Answer = true;
            using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MLYConnectionString"].ConnectionString))
            {
                SqlCommand cmd = new SqlCommand("CheckDatesOnUpdate", conn);
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add("WorkOrderId", SqlDbType.Int);
                cmd.Parameters["WorkOrderId"].Value = WorkOrderId;

                //DateTime SendDateParced;
                //if (DateTime.TryParse(SendDate.ToString(), out SendDateParced))
                if (SendDate != null)
                {
                    cmd.Parameters.Add("NewSendDate", SqlDbType.DateTime);
                    cmd.Parameters["NewSendDate"].Value = SendDate.ToString();
                }
                //DateTime RequestedDelivaryDateParced;
                //if (DateTime.TryParse(RequestedDelivaryDate.ToString(), out RequestedDelivaryDateParced))
                if(RequestedDelivaryDate != null)
                {
                    cmd.Parameters.Add("NewRequestedDelivaryDate", SqlDbType.DateTime);
                    cmd.Parameters["NewRequestedDelivaryDate"].Value = RequestedDelivaryDate.ToString();
                }
                //DateTime PlannedDelivaryDateParced;
                //if (DateTime.TryParse(PlannedDelivaryDate.ToString(),  out PlannedDelivaryDateParced))
                if (PlannedDelivaryDate != null)
                {
                    cmd.Parameters.Add("NewPlannedDelivaryDate", SqlDbType.DateTime);
                    cmd.Parameters["NewPlannedDelivaryDate"].Value = PlannedDelivaryDate.ToString();
                }
                //DateTime ActualDelivaryDateParced;
                //if (DateTime.TryParse(ActualDelivaryDate.ToString(), out ActualDelivaryDateParced))
                if (ActualDelivaryDate != null)
                {
                    cmd.Parameters.Add("NewActualDelivaryDate", SqlDbType.DateTime);
                    cmd.Parameters["NewActualDelivaryDate"].Value = ActualDelivaryDate.ToString();
                }
                //DateTime DateFieldAParced;
                //if (DateTime.TryParse(DateFieldA.ToString(), out DateFieldAParced))
                if (DateFieldA != null)
                {
                    cmd.Parameters.Add("NewDateFieldA", SqlDbType.DateTime);
                    cmd.Parameters["NewDateFieldA"].Value = DateFieldA.ToString();
                }
                //DateTime DateFieldBParced;
                //if (DateTime.TryParse(DateFieldB.ToString(), out DateFieldBParced))
                if (DateFieldB != null)
                {
                    cmd.Parameters.Add("NewDateFieldB", SqlDbType.DateTime);
                    cmd.Parameters["NewDateFieldB"].Value = DateFieldB.ToString();
                }
                //DateTime OriginalPlannedDeliveryDateParced;
                //if (DateTime.TryParse(OriginalPlannedDeliveryDate.ToString(), out OriginalPlannedDeliveryDateParced))
                if (OriginalPlannedDeliveryDate != null)
                {
                    cmd.Parameters.Add("NewOriginalPlannedDeliveryDate", SqlDbType.DateTime);
                    cmd.Parameters["NewOriginalPlannedDeliveryDate"].Value = OriginalPlannedDeliveryDate.ToString();
                }
                //DateTime OriginalRequestedDeliveryDateParced;
                //if (DateTime.TryParse(OriginalRequestedDeliveryDate.ToString(), out OriginalRequestedDeliveryDateParced))
                if (OriginalRequestedDeliveryDate != null)
                {
                    cmd.Parameters.Add("NewOriginalPlannedDeliveryDate", SqlDbType.DateTime);
                    cmd.Parameters["NewOriginalRequestedDeliveryDate"].Value = OriginalRequestedDeliveryDate.ToString();
                }
                cmd.Parameters.Add("Answer", SqlDbType.NVarChar, 64);
                cmd.Parameters["Answer"].Direction = ParameterDirection.Output;
                try
                {
                    conn.Open();
                    cmd.ExecuteNonQuery();
                    if (cmd.Parameters["Answer"].Value.ToString() != "OK")
                    {
                        Answer = false;
                        SetEditFormErrorMessage(cmd.Parameters["Answer"].Value.ToString());
                    }
                    else
                    {
                        SetEditFormErrorMessage("");
                    }
                }
                catch (Exception ex)
                {
                    SetEditFormErrorMessage(ex.Message);
                }
                finally
                {
                    conn.Close();
                }
            }
            return Answer;
        }

        // Display split panel and initilaize split process.
        protected void InventoryGrid_CustomButtonCallback(object sender,
                                        ASPxGridViewCustomButtonCallbackEventArgs e)
        {
            switch (e.ButtonID)
            {
                case "SpliterButton":
                    SetErrorMessage("");
                    SpliterTextBox.Text = "";
                    ShowSpliter(true);
                    break;
                case "NewCustomButton":
                    InventoryGrid.AddNewRow();
                    break;
                case "DisqualificationButton":
                    OpenDisqualifyPanel();
                    break;
            }
        }

        protected void SpliterCancelButton_Click(object sender, EventArgs e)
        {
            ShowSpliter(false);
        }

        // Split current work order.
        protected void SpliterUpdateButton_Click(object sender, EventArgs e)
        {
            try
            {
                SetErrorMessage("");

                // Return work order id of the focused inventory grid row or null if there is an error.
                //
                int workOrderID; // ID of work order that should be split.
                if (!TryGetFocusedWorkOrderID(out workOrderID))
                    throw new Exception("Invalid focus row");

                decimal splitQuantity;
                if (!decimal.TryParse(SpliterTextBox.Text, out splitQuantity))
                    throw new Exception("Invalid split quantity");

                clsWorkOrder.SplitWorkOrder(workOrderID, splitQuantity);

                ShowSpliter(false);
                InventoryGrid.DataBind();
            }
            catch (Exception ex)
            {
                SetErrorMessage(ex);
            }
        }

        protected void DistributionGridView_BeforePerformDataSelect(object sender, EventArgs e)
        {
            if (!(sender is ASPxGridView))
                return;
            ASPxGridView distributionGridView = (ASPxGridView)sender;
            object masterRowKeyValue = distributionGridView.GetMasterRowKeyValue();
            if (!(masterRowKeyValue is int))
                return;

            SessParam.MasterWorkWorderID = (int)masterRowKeyValue;

            //Control control = distributionGridView.Parent.FindControl("DistributionPanel");
            //if (control is Panel && control.ID == "DistributionPanel")
            //{
            //  Panel panel = (Panel)control;
            //  if (SessParam.Culture == "he")
            //    panel.HorizontalAlign = HorizontalAlign.Right;
            //  else
            //    panel.HorizontalAlign = HorizontalAlign.Left;
            //}
        }

        protected void InventoryGrid_CustomUnboundColumnData(object sender,
                                                             ASPxGridViewColumnDataEventArgs e)
        {
            switch (e.Column.FieldName)
            {
                case "RequestedBalance":
                    {
                        e.Value = GetRequestedBalance(e.GetWorkOrderID());
                        break;
                    }
                case "PlannedBalance":
                    {
                        e.Value = GetPlannedBalance(e.GetWorkOrderID());
                        break;
                    }
                case "OpenQuantity":
                    {
                        e.Value = clsWorkOrder.GetOpenQuantity(e.GetWorkOrderID());
                        break;
                    }
            }
        }

        #endregion Events

        private bool TestField(KeyValuePair<string, EditFormControl> kvp,
                               string key,
                               string text, ASPxDataInsertingEventArgs e)
        {
            if (kvp.Key != key)
                return false;
            SetMissingErrorMessage(text);
            e.Cancel = true;
            return true;
        }

        // Prevent word warp in Inventory grid columns. 
        // If the text is too long then truncate it and add "..." at the end.
        //public void DisableWordWrap()
        //{
        //  foreach (GridViewColumn column in InventoryGrid.Columns)
        //  {
        //    if (!(column is GridViewDataTextColumn))
        //      continue;
        //    GridViewDataTextColumn textColumn = (GridViewDataTextColumn)column;
        //    string fieldName = textColumn.FieldName;
        //    if (!string.IsNullOrEmpty(fieldName))
        //    {
        //      // In some columns the div, hide the edges, 
        //      // so in those cases we don't use it.
        //      if (fieldName != TableWorkOrder.cnCustomerPriority &&
        //          fieldName != TableWorkOrder.cnTextFieldB && fieldName != TableWorkOrder.cnRemarks &&
        //          fieldName != TableWorkOrder.cnOrderNumber && fieldName != TableWorkOrder.cnSplitId)
        //        textColumn.DataItemTemplate = new InventoryDivTemplate(textColumn.FieldName);
        //    }
        //  }
        //}


        private decimal GetPlannedBalance(int workOrderId)
        {
            return clsWorkOrder.GetInventoryBalance(workOrderId, BalanceType.ByPlannedDate);
        }

        private decimal GetRequestedBalance(int workOrderId)
        {
            return clsWorkOrder.GetInventoryBalance(workOrderId, BalanceType.ByRequestedDate);
        }

        private void SetErrorMessage(string text)
        {
            ErrorMessageLabel.Text = text;
        }

        private void SetErrorMessage(Exception ex)
        {
            SetErrorMessage(ex.Message);
            Log.WriteError("", ex);
        }

        private string FormatCondition(string filter, string fieldName, string value)
        {
            if (string.IsNullOrEmpty(value))
                return filter;
            else
            {
                string Str = string.Format("({0} == {1})", fieldName, value);
                if (string.IsNullOrEmpty(filter))
                    return Str;
                else
                    return filter + " && " + Str;
            }
        }
        

        private void InitializeDataSource()
        {
            string filter = "(originalWoForDist == null)";
            filter = FormatCondition(filter, TableWorkOrder.cnCustomerId, SessParam.CustomerId);
            filter = FormatCondition(filter, TableWorkOrder.cnContractorId, SessParam.ContractorID);

            // Eliminate canceled rows
            string nowStr = (new DateTime(2099, 1, 1)).ToString();
            filter += " && (ActualDelivaryDate.Value.CompareTo(  " + '"' + nowStr + '"' + ") == -1 || ActualDelivaryDate == null)";
            
            // alerts
            //filter += " && ((MarkedUser == null) || (MarkedUser == " + Session["UserId"].ToString() + "))";

            InventoryDataSource.Where = filter;            
            //InventoryGrid.FilterExpression = filter;
        }

        void SetClient()
        {
            if (Request.QueryString["IsClient"] != null)
            {
                if (Request.QueryString["ContractorId"] != null)
                    SessParam.ContractorID = Request.QueryString["ContractorId"].ToString();
                SessParam.CustomerId = SessParam.OrganizationId.ToString();
                SessParam.IsClient = true;
            }
            else
            {
                if (Request.QueryString["ClientID"] != null)
                    SessParam.CustomerId = Request.QueryString["ClientID"].ToString();
                SessParam.ContractorID = SessParam.OrganizationId.ToString();
                SessParam.IsClient = false;
            }
        }

        //private void CopyFocusDateToNewValue(ASPxDataUpdatingEventArgs e, string fieldName)
        //{
        //  DateTime value;
        //  if (TryGetDateFocusedRowValue(fieldName, out value))
        //    e.SetNewValueDateTime(fieldName, value);
        //}

        private void SetMissingErrorMessage(string dictKey)
        {
            SetEditFormErrorMessage("Missing " + Dictionary.Translate(dictKey));
        }

        private void SetEditFormErrorMessage(string text)
        {
            SessParam.EditFormErrorMessage = text;
        }

        // Update Quantity and if necessary make distribution.
        private void UpdateQuantity(ASPxTextBox textBox,
                                    ref bool isDistribution,
                                    InventoryEditForm editForm,
                                    ASPxDataUpdatingEventArgs e)
        {
            // Retrive existing value of work order quantity from inventoryGrid.
            decimal oldQuantity;
            if (!TryGetDecimalFocusedRowValue(TableWorkOrder.cnQuantity, out oldQuantity))
                return;
            // Retrive sent quantity from its edit box.
            decimal newQuantity;
            if (!decimal.TryParse(textBox.Text, out newQuantity))
                return;
            // Both quantities has same value, so there is noting to do.
            if (decimal.Equals(oldQuantity, newQuantity))
                return;

            if (newQuantity < oldQuantity)
            {
                isDistribution = true;
                // Sent quantity is less then current quantitiy, 
                // so we make distributtion.
                // 
                int workOrderID; // ID of work order that should be split.
                if (!TryGetFocusedWorkOrderID(out workOrderID))
                    throw new Exception("Invalid focuse row");

                DateTime? actualDelivaryDate = editForm.GetDate(TableWorkOrder.cnActualDelivaryDate);
                DateTime? plannedDelivaryDate = editForm.GetDate(TableWorkOrder.cnPlannedDelivaryDate);
                clsWorkOrder.CreateDist(workOrderID, newQuantity, actualDelivaryDate, plannedDelivaryDate);

                // If it less that the Wo Q. then decrease the WO Q. to the remaining Q. (also, dist. line was added earlier in this code).
                e.SetNewValueDecimal(TableWorkOrder.cnQuantity, oldQuantity - newQuantity);
            }
            else
                if (newQuantity > oldQuantity)
                {
                    e.SetNewValueDecimal(TableWorkOrder.cnQuantity, newQuantity);
                }
        }

        // Hide or show spliter controls. 
        // Also enable/disable inventory grid.
        private void ShowSpliter(bool value)
        {
            SpliterPanelNew.Visible = value;           
            InventoryGrid.Enabled = !value;
            
        }

        // Return work order id of the focused inventory grid row or null if there is an error.
        private bool TryGetFocusedWorkOrderID(out int woID)
        {
            return TryGetIntFocusedRowValue(TableWorkOrder.cnWorkOrderId, out woID);
        }

        private bool TryGetFocusedRowValue(string fieldName, out object value)
        {
            if (InventoryGrid.FocusedRowIndex == -1)
            {
                value = null;
                return false;
            }
            value = InventoryGrid.GetRowValues(InventoryGrid.FocusedRowIndex, fieldName);
            return true;
        }

        private bool TryGetDecimalFocusedRowValue(string fieldName, out decimal value)
        {
            object obj;
            if (TryGetFocusedRowValue(fieldName, out obj))
            {
                if (obj is decimal)
                {
                    value = (decimal)obj;
                    return true;
                }
            }
            value = decimal.MinValue;
            return false;
        }

        private DateTime? GetDateFocusedRowValue(string fieldName)
        {
            DateTime value;
            if (TryGetDateFocusedRowValue(fieldName, out value))
                return value;
            else
                return null;
        }

        private bool TryGetDateFocusedRowValue(string fieldName, out DateTime value)
        {
            object obj;
            if (TryGetFocusedRowValue(fieldName, out obj))
            {
                if (obj is DateTime)
                {
                    value = (DateTime)obj;
                    return true;
                }
            }
            value = DateTime.MinValue;
            return false;
        }

        private bool TryGetIntFocusedRowValue(string fieldName, out int value)
        {
            object obj;
            if (TryGetFocusedRowValue(fieldName, out obj))
            {
                if (obj is int)
                {
                    value = (int)obj;
                    return true;
                }
            }
            value = int.MinValue;
            return false;
        }
 

        protected void RemoveSelectedPaka(object sender, EventArgs e)
        {
            TMPMessageLabel.Text = "";
            string[] ToRemoveIds = ToRemoveArrayHiddenField.Value.Split(',');

            for (int i = 0; i < ToRemoveIds.Length; i++)
            {
                RemoveWorkOrder(ToRemoveIds[i], false);
                InventoryGrid.DataBind();
            }

            ToRemoveArrayHiddenField.Value = "";
        }

        private void RemoveWorkOrder(string WOId, bool disqualify)
        {
            using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MLYConnectionString"].ConnectionString))
            {
                SqlCommand cmd = new SqlCommand("MarkOrderAsDeleted", conn);
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add("OrderId", SqlDbType.Int);
                cmd.Parameters["OrderId"].Value = WOId;

                cmd.Parameters.Add("Disqualify", SqlDbType.Bit);
                cmd.Parameters["Disqualify"].Value = disqualify;

                cmd.Parameters.Add("UpdatedBy", SqlDbType.Int);
                cmd.Parameters["UpdatedBy"].Value = SessParam.UserId;

                try
                {
                    conn.Open();
                    cmd.ExecuteNonQuery();
                    TMPMessageLabel.Text += ("OrderId " + WOId + " deleted successfully<br /> ");
                }
                catch (Exception ex)
                {
                    TMPMessageLabel.Text += ex.Message;
                }
                finally
                {
                    conn.Close();
                }
            }
        }

        private void AddCancelReasonToPaka(string ReasonId, string WOId)
        {
            using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MLYConnectionString"].ConnectionString))
            {
                SqlCommand cmd = new SqlCommand("SCCover_AddWOCancelReason", conn);
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add("WorkOrderId", SqlDbType.Int);
                cmd.Parameters["WorkOrderId"].Value = WOId;

                cmd.Parameters.Add("CancelReason", SqlDbType.Int);
                cmd.Parameters["CancelReason"].Value = ReasonId;

                try
                {
                    conn.Open();
                    cmd.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    Log.WriteError(ex.Message);
                }
                finally
                {
                    conn.Close();
                }
            }
        }

        private bool IsGroupRow(int visibleIndex)
        {
            int rowLevel = InventoryGrid.GetRowLevel(visibleIndex);
            return rowLevel != InventoryGrid.GetGroupedColumns().Count;
        }

        protected bool IsRowMarked(object OrderId)
        { 
            bool Answer = false;
            using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MLYConnectionString"].ConnectionString))
            {
                SqlCommand cmd = new SqlCommand("IsRowMarked", conn);
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.AddWithValue("OrderId", OrderId.ToString());
                cmd.Parameters.AddWithValue("UserId", Session["UserId"].ToString());
                cmd.Parameters.Add("IsMarked", SqlDbType.Bit);
                cmd.Parameters["IsMarked"].Direction = ParameterDirection.Output;

                try
                {
                    conn.Open();
                    cmd.ExecuteNonQuery();
                    Answer = (bool)cmd.Parameters["IsMarked"].Value;
                }
                catch (Exception ex)
                {
                    SetEditFormErrorMessage(ex.Message);
                }
                finally
                {
                    conn.Close();
                }

            }
            return Answer;
        }

        protected void ASPxGridView1_HtmlRowPrepared(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewTableRowEventArgs e)
        {
            try
            {
                if (e.RowType != GridViewRowType.Data) return;
                //if (e.GetValue("TableUserWorkOrderMarking.UserId") != null)
                if (IsRowMarked(e.GetValue("WorkOrderId")))
                {
                    e.Row.BackColor = Color.LightBlue;
                    e.Row.ForeColor = Color.Black;
                }

                // DEMO CODE
                // The demo will highlight 2-nd and 7th rows
                if ((string)Session["DemoStage"] == "Alerts")
                {
                    if ((CurrentrowNum == 2) || (CurrentrowNum == 7))
                    {
                        e.Row.BackColor = Color.LightBlue;
                        e.Row.ForeColor = Color.Black;                         
                    }
                    CurrentrowNum++;
                }
                // EOF DEMO CODE
            }
            catch { }
            //Log.WriteInfo("HtmlRowPrepared finish: " + CurDate());

        
        }

        protected void btnPdfExport_Click(object sender, EventArgs e)
        {
            Response.Clear();

            gridExport.WritePdfToResponse();
        }
        protected void btnXlsExport_Click(object sender, EventArgs e)
        {
            // DEMO CODE
            if (((string)Session["DemoCode"] == "3") && ((sender as Control).ID == "ExportToXLS"))
            {
                // The following two lines were moved to client
                //ExportToXLS.CssClass = "demostophighlight";
                //(Master.FindControl("DemoLabel") as Label).Text = "You can do many things with your data here. Like adding new rows, edit your data, or advanced filtering.<br /> When ready for the next part of the demo - go to the Advanced reports in the menu";
                Session["DemoCode"] = "4";
            }
            // EOF DEMO CODE

            Response.Clear();
            gridExport.WriteXlsToResponse();
            
        }
        protected void btnXlsxExport_Click(object sender, EventArgs e)
        {
            Response.Clear();
            gridExport.WriteXlsxToResponse();
        }
        protected void btnRtfExport_Click(object sender, EventArgs e)
        {
            Response.Clear();
            gridExport.WriteRtfToResponse();
        }
        protected void btnCsvExport_Click(object sender, EventArgs e)
        {
            gridExport.WriteCsvToResponse();
        }

        protected string GetOrgNameById(object _OrgId)
        {
            string OrgName = "";
            try
            {
                OrgName = MLY.Bll.clsOrganization.GetOrgNameById(int.Parse(_OrgId.ToString()));
            }
            catch { }
            return OrgName;

        }

        protected void MarkSelectedAsDebate(object sender, EventArgs e)
        {
            TMPMessageLabel.Text = "";
            string[] ToRemoveIds = ToggleDebateArrayHiddenField.Value.Split(',');

            for (int i = 0; i < ToRemoveIds.Length; i++)
            {
                using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MLYConnectionString"].ConnectionString))
                {
                    SqlCommand cmd = new SqlCommand("ToggleDebateValue", conn);
                    cmd.CommandType = CommandType.StoredProcedure;

                    cmd.Parameters.Add("OrderId", SqlDbType.Int);
                    cmd.Parameters["OrderId"].Value = ToRemoveIds[i];

                    cmd.Parameters.Add("UpdatedBy", SqlDbType.Int);
                    cmd.Parameters["UpdatedBy"].Value = SessParam.UserId;

                    try
                    {
                        conn.Open();
                        cmd.ExecuteNonQuery();
                        TMPMessageLabel.Text += ("OrderId " + ToRemoveIds[i] + " toggled<br /> ");
                    }
                    catch (Exception ex)
                    {
                        TMPMessageLabel.Text += ex.Message + "<br />";
                    }
                    finally
                    {
                        conn.Close();
                    }

                }
                InventoryGrid.DataBind();
            }

            ToggleDebateArrayHiddenField.Value = "";
        }

        protected void CancelDisqualify(object sender, EventArgs e)
        {
            HideDisqualifyPanel();            
        }

        private void HideDisqualifyPanel()
        {
            DisqualifyWOId.Value = "";
            QuantityHF.Value = "";
            DisqualifyMessageLabel.Text = "";
            DisqualifyQtyTextBox.Text = "";
            DisqualifyPanel.Visible = false;
        }

        protected void DisqualifyWorkOrder(object sender, EventArgs e)
        {
            if (CanDisqualify())
            {
                try
                {
                    int WOId = int.Parse(DisqualifyWOId.Value);
                    decimal QuantityToDisqualify = decimal.Parse(DisqualifyQtyTextBox.Text.Trim());
                    decimal OriginalQuantity = decimal.Parse(QuantityHF.Value);

                    if (QuantityToDisqualify > OriginalQuantity)
                        DisqualifyMessageLabel.Text = "Disqualify amount is larger then quantity";
                    else
                    {
                        if (QuantityToDisqualify == OriginalQuantity)
                        {
                            RemoveWorkOrder(WOId.ToString(), true);
                            HideDisqualifyPanel();
                        }
                        else
                        {
                            int newWO = clsWorkOrder.SplitWorkOrderWithDisqalify(WOId, QuantityToDisqualify);
                            SetDisqualifyReasons(newWO);
                        }
                        //HideDisqualifyPanel();
                        // cleaning and leaving the area open:
                        DisqualifyQtyTextBox.Text = "";
                        foreach (RepeaterItem item in DeleteReasonsRepeater.Items)
                        {
                            (item.FindControl("ReasonCheckBox") as CheckBox).Checked = false;
                        }
                        QtyLabel.Text = QtyLabel.Text.Replace("Current quantity: " + QuantityHF.Value, "Current quantity: " + (OriginalQuantity - QuantityToDisqualify).ToString());
                        QuantityHF.Value = (OriginalQuantity - QuantityToDisqualify).ToString();

                        OpenDisqualifyPanel(WOId);
                        PostDisqualifyMessage.Visible = true;
                        InventoryGrid.DataBind();

                    }
                }
                catch (Exception ex)
                {
                    DisqualifyMessageLabel.Text = ex.Message;
                }
            }
            else
            {
                DisqualifyMessageLabel.Text = Dictionary.Translate("Inventory.DisqualifyErrorText");
            }
            
        }

        private bool CanDisqualify()
        {
            bool Can = false;
            if (DisqualifyQtyTextBox.Text.Trim().Length == 0) return false;
            
            foreach (RepeaterItem item in DeleteReasonsRepeater.Items)
            {
                if ((item.FindControl("ReasonCheckBox") as CheckBox).Checked)
                    Can = true;
            }

            return Can;
        }

        protected void SetDisqualifyReasons(int WOId)
        {
            foreach (RepeaterItem item in DeleteReasonsRepeater.Items)
            {
                if ((item.FindControl("ReasonCheckBox") as CheckBox).Checked)
                {
                    AddCancelReasonToPaka((item.FindControl("ReasonIdHiddenField") as HiddenField).Value, WOId.ToString());
                    (item.FindControl("ReasonCheckBox") as CheckBox).Checked = false;
                }
            }
        }

        private void OpenDisqualifyPanel(int WOId)
        {
            string CustomerWONumber = "", ContractorWONumber = "", CustomerCatalogueCode = "",
                ContractorCatalogueCode = "", ContractorLotNumber = "", previousDisqualifications = "";

            decimal Quantity = 0;
            DisqualifyQtyTextBox.Text = "";

            clsWorkOrder workOrder = new clsWorkOrder(WOId);
            CustomerWONumber = workOrder.Data.ContractorWorkOrderNumber;
            ContractorWONumber = workOrder.Data.ContractorWorkOrderNumber;
            CustomerCatalogueCode = workOrder.Data.CustomerCatalougeCode;
            ContractorCatalogueCode = workOrder.Data.ContractorCatalogueCode;
            ContractorLotNumber = workOrder.Data.ContractorLotNumber;
            if (workOrder.Data.Quantity.HasValue)
                Quantity = workOrder.Data.Quantity.Value;

            DisqualifyWOId.Value = WOId.ToString();
            QuantityHF.Value = Quantity.ToString();
            DisqualifyMessageLabel.Text = "";
            QtyLabel.Text = "Work order details: " + CustomerWONumber + " " + ContractorWONumber + " " +
                CustomerCatalogueCode + " " + ContractorCatalogueCode + " " + ContractorLotNumber + " " +
                GetWOIdDisqualifications(WOId) + "<br /> Current quantity: " + Quantity.ToString() +
                ". Disqualify quantity: ";
            DisqualifyPanel.Visible = true;
            PostDisqualifyMessage.Visible = false;
        }
        protected void OpenDisqualifyPanel()
        {
            
            int WOId = 0;
            
            if (TryGetFocusedWorkOrderID(out WOId))
            {
                OpenDisqualifyPanel(WOId);
            }
            else
            {
                DisqualifyMessageLabel.Text = "Failed to read work order details";
            }
        }

        private string GetWOIdDisqualifications(int WOId)
        {
            string previousDisqualifications = "<br /> No previous disqualifications<br /> ";

            using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MLYConnectionString"].ConnectionString))
            {
                SqlCommand cmd = new SqlCommand("SCCOver_GetDisqualificationsForWorkOrder", conn);
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add("WorkOrderId", SqlDbType.Int);
                cmd.Parameters["WorkOrderId"].Value = WOId;

                SqlDataReader myreader;

                try
                {
                    conn.Open();
                    myreader = cmd.ExecuteReader();
                    if (myreader.HasRows)
                    {
                        previousDisqualifications = "<br /> Previous disqualifications:";
                        while (myreader.Read())
                        {
                            previousDisqualifications += "<br /> Quantity: ";
                            previousDisqualifications += myreader.GetDecimal(0);
                            previousDisqualifications += " Reason: ";
                            previousDisqualifications += myreader.GetString(1);
                        }
                        previousDisqualifications += "<br /> ";
                    }
                    myreader.Close();

                }
                catch (Exception ex)
                {
                    Log.WriteError(ex.Message);
                }
                finally
                {
                    conn.Close();
                }

            }

            return previousDisqualifications;
        }

        protected string LotNumberSortValue(object LotNumber)
        {
            // sorting trick for Lithotech only
            string ReturnValue = (string)LotNumber;
            
            if (ReturnValue.StartsWith("13-"))
                ReturnValue.Remove(0, 3);
            else
                return ReturnValue;

            while (ReturnValue.Length < 5)
                ReturnValue = "0" + ReturnValue;

            return ReturnValue;
        }

    }
}